package com.ccb.util;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

//import net.sf.json.JSONArray;
//import net.sf.json.JSONObject;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 
 * <p>
 * Title: JSON-XML转换工具
 * </p>
 * <p>
 * desc:
 * <p>
 * Copyright: Copyright(c)Gb 2012
 * </p>
 * 
 * @author http://www.ij2ee.com
 * @time 上午8:20:40
 * @version 1.0
 * @since
 */
public class XmlJSON {
	@SuppressWarnings("unchecked")
	public static String xmlToJSON(String xml, int jsonType) {
		JSONObject obj = new JSONObject();

		try {
			InputStream is = new ByteArrayInputStream(xml.getBytes("utf-8"));
			SAXBuilder sb = new SAXBuilder();
			Document doc = sb.build(is);
			// System.out.println("doc"+doc.getBaseURI());
			Element root = doc.getRootElement();
			List<Attribute> atlist = root.getAttributes();
			Map map = iterateElement(root);
			for (Attribute at : atlist) {
				map.put("@" + at.getName(), at.getValue());
			}
			obj.put(root.getName(), map);
			return obj.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	public static JSONObject xmlToJSONObj(String xml) {
		JSONObject obj = new JSONObject();
		try {
			InputStream is = new ByteArrayInputStream(xml.getBytes("utf-8"));
			SAXBuilder sb = new SAXBuilder();
			Document doc = sb.build(is);
			Element root = doc.getRootElement();
			List<Attribute> atlist = root.getAttributes();
			Map map = iterateElement(root);
			for (Attribute at : atlist) {
				map.put("@" + at.getName(), at.getValue());
			}
			obj.put(root.getName(), map);
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static Map iterateElement(Element root) {
		List childrenList = root.getChildren();
		List<Attribute> atlist = root.getAttributes();
		Element element = null;
		Map map = new HashMap();
		for (Attribute at : atlist) {
			map.put("@" + at.getName(), at.getValue());
		}
		List list = null;
		for (int i = 0; i < childrenList.size(); i++) {
			list = new ArrayList();
			element = (Element) childrenList.get(i);
			List<Attribute> etlist = element.getAttributes();
			if (element.getChildren().size() > 0) {
				if (root.getChildren(element.getName()).size() > 1) {
					if (map.containsKey(element.getName())) {
						list = (List) map.get(element.getName());
					}
					list.add(iterateElement(element));
					map.put(element.getName(), list);
				} else {
					map.put(element.getName(), iterateElement(element));
				}
			} else {
				if (root.getChildren(element.getName()).size() > 1) {
					if (map.containsKey(element.getName())) {
						list = (List) map.get(element.getName());
					}
					if (etlist.size() > 0) {
						Map attmap = new HashMap();
						for (Attribute at : etlist) {
							attmap.put("@" + at.getName(), at.getValue());
						}
						attmap.put("#text", element.getTextTrim());
						list.add(attmap);
						// map.put(element.getName(), attmap);
					} else {
						list.add(element.getTextTrim());

					}
					map.put(element.getName(), list);
				} else {

					if (etlist.size() > 0) {
						Map attmap = new HashMap();
						for (Attribute at : etlist) {
							attmap.put("@" + at.getName(), at.getValue());
						}
						attmap.put("#text", element.getTextTrim());
						map.put(element.getName(), attmap);
					} else {
						map.put(element.getName(), element.getTextTrim());
					}

				}
			}
		}

		return map;
	}

	public static String JsonToXml(Object json) {
		Document document = new Document();
		if (json == null) {
			return null;
		} else {
			if (json instanceof JSONObject) {
				String rootStr = "";
				Object childValue = null;
				Element child = null;
				JSONObject jsonObject = (JSONObject) json;
				for (Object temp : jsonObject.keySet()) {
					rootStr = temp.toString();
					childValue = jsonObject.get(temp);
					child = new Element(rootStr);

				}
				getXMLFromObject(childValue, "", child);
				document.addContent(child);
				XMLOutputter xmlOut = new XMLOutputter();
				Format format = Format.getPrettyFormat();
				format.setEncoding("UTF-8");
				xmlOut.setFormat(format);
				String res = xmlOut.outputString(document);
				return res;

			} else {
				Element elements = new Element("kkk");
				getXMLFromObject(json, "", elements);
				XMLOutputter xmlOut = new XMLOutputter();
				String res = xmlOut.outputString(elements);
				return res;
			}

		}
	}

	private static void getXMLFromObject(Object obj, String tag, Element parent) {
		if (obj == null)
			return;
		Element child;
		String eleStr;
		Object childValue;
		if (obj instanceof JSONObject) {
			JSONObject jsonObject = (JSONObject) obj;
			for (Object temp : jsonObject.keySet()) {
				eleStr = temp.toString();
				childValue = jsonObject.get(temp);
				if (temp.toString().startsWith("@")) {
					parent.setAttribute(temp.toString().substring(1), childValue.toString());
				} else if (temp.toString().startsWith("#text")) {
					parent.setText(childValue.toString());
				} else {
					child = new Element(eleStr);
					if (childValue instanceof JSONArray)
						getXMLFromObject(childValue, eleStr, parent);
					else {
						parent.addContent(child);
						getXMLFromObject(childValue, eleStr, child);
					}
				}

			}
		} else if (obj instanceof JSONArray) {
			JSONArray jsonArray = (JSONArray) obj;
			for (int i = 0; i < jsonArray.size(); i++) {
				childValue = jsonArray.get(i);
				child = new Element(tag);
				parent.addContent(child);
				getXMLFromObject(childValue, tag, child);
			}
		} else if (obj instanceof Date) {
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			parent.setText(sf.format((Date) obj));
		} else {
			parent.setText(obj.toString());
		}
	}

	public static void main(String[] args) {
		String jsonb = "<?xml version=\"1.0\"?><root name='ddd'>" + "<jydm name=\"213\">201005</jydm>" + "<xym name='222'>222</xym><xym name='333'>333</xym>" + "<slyhh>634324301005</slyhh>" + "<warning><str name='123'>sss</str><str name='321'>sss2</str></warning>" + "<warning123>ffff</warning123>" + "</root>";
		String jsona = "<?xml version=\"1.0\"?><root>" + "<jydm >201005</jydm>" + "<xym >222</xym><xym >333</xym>" + "<slyhh>634324301005</slyhh>" + "<warning><str>sss</str><str>sss2</str></warning>" + "<warning123>ffff</warning123>" + "</root>";
		String jsonx = "{\"root\":{\"slyhh\":\"634324301005\",\"warning\":{\"str\":[\"sss\",\"sss2\"]},\"warning123\":\"ffff\",\"jydm\":\"201005\",\"xym\":[\"222\",\"333\"]}}";
		// String xml = json2XML(STR_JSON);
		// System.out.println("xml = "+xml);
		// System.out.println(xmlToJSON(jsonb, 1));
		// System.out.println(JSONObject.fromObject(xmlToJSON(jsonb, 1)));
		JSONObject o = xmlToJSONObj(jsona);
		// System.out.println("json=\n"+o.toString());;
		//
		// System.out.println("xml=\n"+JsonToXml(JSONObject.fromObject(jsonx)));
		System.out.println("old=\n" + jsonb);
		System.out.println("json=\n" + xmlToJSONObj(jsonb));
		System.out.println("xml=\n" + JsonToXml(xmlToJSONObj(jsonb)));
		// System.out.println(xmlToJSON(jsonb, 1));
	}
}